/*
 * Copyright (c) 2024 Endless
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HAL_NET_INCLUDE_HAL_NETWORK_H
#define HAL_NET_INCLUDE_HAL_NETWORK_H

#include <string>
#include <vector>
#include <map>
#include <memory>

namespace El {
namespace Hal {

// 网络接口类型
enum class NetIfType {
    UNKNOWN = 0,
    ETHERNET, // 以太网
    WIFI,     // WiFi
    LOOPBACK, // 回环
    CELLULAR, // 蜂窝网络
};

// 网络状态
enum class NetIfStatus {
    DOWN = 0, // 接口关闭
    UP,       // 接口开启
    UNKNOWN,  // 未知状态
};

// 网络配置类型
enum class AddressType {
    IPV4 = 0,
    IPV6,
};

// 网络接口信息
struct NetIfInfo {
    std::string name;        // 接口名称，如eth0
    std::string macAddress;  // MAC地址
    NetIfType type;          // 接口类型
    NetIfStatus status;      // 接口状态
    bool hasIpv4;            // 是否有IPv4地址
    std::string ipv4Address; // IPv4地址
    std::string ipv4Mask;    // IPv4子网掩码
    std::string gateway;     // 默认网关
};

// IP地址信息
struct IpAddressInfo {
    std::string address;   // IP地址
    std::string netmask;   // 子网掩码（IPv4）或前缀长度（IPv6）
    std::string broadcast; // 广播地址（仅IPv4）
    AddressType type;      // 地址类型
};

// 路由信息
struct RouteInfo {
    std::string destination; // 目标网络
    std::string gateway;     // 网关
    std::string netmask;     // 子网掩码
    std::string ifname;      // 接口名称
    int metric;              // 跃点数
};

class NetworkManager {
public:
    /**
     * @brief 获取NetworkManager单例实例
     * @return NetworkManager实例
     */
    static NetworkManager &GetInstance();

    /**
     * @brief 获取所有网络接口信息
     * @return 网络接口信息列表
     */
    std::vector<NetIfInfo> GetNetworkInterfaces();

    /**
     * @brief 获取指定网络接口信息
     * @param ifname 接口名称
     * @return 网络接口信息，如果接口不存在则返回空对象
     */
    NetIfInfo GetNetworkInterface(const std::string &ifname);

    /**
     * @brief 设置接口状态（启用或禁用）
     * @param ifname 接口名称
     * @param status 目标状态
     * @return 成功返回true，失败返回false
     */
    bool SetInterfaceStatus(const std::string &ifname, NetIfStatus status);

    /**
     * @brief 配置静态IP地址
     * @param ifname 接口名称
     * @param address IP地址
     * @param netmask 子网掩码（IPv4）或前缀长度（IPv6）
     * @param gateway 默认网关（可选）
     * @return 成功返回true，失败返回false
     */
    bool ConfigureStaticIp(const std::string &ifname,
                           const std::string &address,
                           const std::string &netmask,
                           const std::string &gateway = "");

    /**
     * @brief 配置DHCP
     * @param ifname 接口名称
     * @return 成功返回true，失败返回false
     */
    bool ConfigureDhcp(const std::string &ifname);

    /**
     * @brief 添加路由
     * @param destination 目标网络
     * @param gateway 网关
     * @param netmask 子网掩码
     * @param ifname 接口名称
     * @param metric 跃点数（可选）
     * @return 成功返回true，失败返回false
     */
    bool AddRoute(const std::string &destination,
                  const std::string &gateway,
                  const std::string &netmask,
                  const std::string &ifname,
                  int metric = 0);

    /**
     * @brief 删除路由
     * @param destination 目标网络
     * @param gateway 网关
     * @param netmask 子网掩码
     * @param ifname 接口名称
     * @return 成功返回true，失败返回false
     */
    bool DeleteRoute(const std::string &destination,
                     const std::string &gateway,
                     const std::string &netmask,
                     const std::string &ifname);

    /**
     * @brief 获取路由表
     * @return 路由信息列表
     */
    std::vector<RouteInfo> GetRouteTable();

    /**
     * @brief 设置DNS服务器
     * @param servers DNS服务器列表
     * @return 成功返回true，失败返回false
     */
    bool SetDnsServers(const std::vector<std::string> &servers);

    /**
     * @brief 获取DNS服务器
     * @return DNS服务器列表
     */
    std::vector<std::string> GetDnsServers();

private:
    NetworkManager();
    ~NetworkManager();

    NetworkManager(const NetworkManager &) = delete;
    NetworkManager &operator=(const NetworkManager &) = delete;

    // 执行shell命令并获取输出
    std::string ExecuteCommand(const std::string &command);

    // 解析IP命令输出
    NetIfInfo ParseIpAddressOutput(const std::string &output, const std::string &ifname);

    // 获取接口类型
    NetIfType GetInterfaceType(const std::string &ifname);

    // 检查接口是否存在
    bool IsInterfaceExist(const std::string &ifname);
};

} // namespace Hal
} // namespace El

#endif // HAL_NET_INCLUDE_HAL_NETWORK_H
